package com.gitee.wsl.collections.map

import com.gitee.wsl.func.Supplier
import com.gitee.wsl.func.Function

/**
 * A Map implementation based on a known [set][Set] of keys and a [ ] that when given a key can derive the value. Once a value has been
 * derived for a key the function will not be called again for the same key.
 *
 *
 * This map can be mutated outside of the original set of keys or within the
 * set of keys. The latter will result in the function not being called for the
 * respective keys.
 *
 *
 * This implementation is the inverse to a [MapSet] which can trivially
 * distill a Map of keys and values to a Set of keys. With the use of a Function
 * this implementation allows a Set of keys to be converted lazily to a Map of
 * keys and values.
 *
 * @author hr  2016.09.29
 * @since 12.2.1.4.0
 */
//class SetMap<K, V>(
//    setKeys: Set<K>,
//    functionValue: Function<K,V>,
//    supplierMap: Supplier<Map<K,V>>
//) : AbstractMutableMap<K,V>() {
//    // ----- constructors ---------------------------------------------------
//    /**
//     * Construct a SetMap.
//     *
//     * @param setKeys  a set of keys to base this Map on
//     */
//    constructor(setKeys: Set<K>) : this(setKeys, Function { k -> null })
//
//    /**
//     * Construct a SetMap.
//     *
//     * @param setKeys        a set of keys to base this Map on
//     * @param functionValue  a [Function] to derive the value for a given
//     * key
//     */
//    constructor(setKeys: Set<K>, functionValue: Function<K,V>) : this(
//        setKeys,
//        functionValue,
//        Supplier { HashMap() })
//
//    override val size: Int
//        get() = internalMap.size
//
//    // ----- Map interface --------------------------------------------------
//
//
//    public override fun isEmpty(): Boolean {
//        return internalMap.isEmpty()
//    }
//
//    public override fun containsKey(key: K): Boolean {
//        return internalMap.containsKey(key)
//    }
//
//    public override fun get(key: K): V? {
//        return ensureValue(key)
//    }
//
//    public override fun put(key: K, value: V): V? {
//        return this.externalMap.put(key, value)
//    }
//
//    public override fun remove(key: K): V? {
//        ensureValue(key)
//
//        return this.externalMap.remove(key)
//    }
//
//    public override fun putAll(map: Map<out K,  V>) {
//        this.externalMap.putAll(map)
//    }
//
//    public override fun clear() {
//        this.externalMap.clear()
//    }
//
//    public override fun keySet(): Set<K> {
//        return this.externalMap.keySet()
//    }
//
//    public override fun entrySet(): Set<Entry<K,V>?> {
//        return ConverterCollections.< Entry < K, Object>, Entry<K, V>>getSet<Entry<K?, kotlin.Any?>?, Entry<K,V>?>(
//        this.internalMap.entrySet(),
//        { entry ->
//            if (entry.getValue() === NO_VALUE) {
//                entry.setValue(f_functionValue.apply(entry.getKey()))
//            }
//            entry as Entry<K,V>
//        },
//        NullImplementation.getConverter())
//    }
//
//    // ----- helpers --------------------------------------------------------
//
//    protected val externalMap: Map<K,V>?
//        /**
//         * Return an external map allowing type safe access.
//         *
//         * @return an external map
//         */
//        get() = this.internalMap as Map<K,V>?
//
//    /**
//     * Return a value for the specified key.
//     *
//     * @param oKey  the key to load a value for
//     *
//     * @return a value for the specified key
//     */
//    protected fun ensureValue(oKey: Any?): V? {
//        val key = oKey as K?
//        val oValue = this.internalMap.get(key)
//        val value: V?
//        if (oValue === NO_VALUE) {
//            this.externalMap.put(key, f_functionValue.apply(key).also { value = it })
//        } else {
//            value = oValue as V?
//        }
//        return value
//    }
//
//    // ----- data members ---------------------------------------------------
//    /**
//     * Return the internal map allowing any object to be stored.
//     *
//     * @return the internal map
//     */
//    /**
//     * The underlying map.
//     */
//    protected var internalMap: MutableMap<K, Any?> = supplierMap.get() as Map<K, Any?>
//
//    /**
//     * A function to load a value for a provided key.
//     */
//    protected var f_functionValue: Function<K,V> = functionValue
//
//    /**
//     * Construct a SetMap.
//     *
//     * @param setKeys        a set of keys to base this Map on
//     * @param functionValue  a [Function] to derive the value for a given
//     * key
//     * @param supplierMap    the Map to use to hold keys and values
//     */
//    init {
//        for (key in setKeys) {
//            internalMap.put(key, NO_VALUE)
//        }
//    }
//
//    companion object {
//        // ----- constants ------------------------------------------------------
//        /**
//         * A reference that indicates a value has not been loaded using the function.
//         */
//        private val NO_VALUE = Any()
//    }
//}
